/*
 * Copyright 2000-2006 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.intellij.gwt.run;

import com.intellij.execution.CantRunException;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.*;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.runners.RunnerInfo;
import com.intellij.gwt.GwtBundle;
import com.intellij.gwt.GwtConfiguration;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.ProjectJdk;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;

import java.util.Collection;

import org.jetbrains.annotations.Nullable;
import org.jdom.Element;

public class GwtRunConfiguration extends ModuleBasedConfiguration {
  public String VM_PARAMETERS = "";
  public String RUN_PAGE = "";
  public boolean NO_SERVER = false;
  public String SERVER_URL = "";

    public GwtRunConfiguration(String name, Project project, GwtRunConfigurationFactory configurationFactory) {
    super(name, new RunConfigurationModule(project, true), configurationFactory);
  }

  public GwtRunConfiguration(Project project, GwtRunConfigurationFactory configurationFactory) {
    this(GwtBundle.message("default.gwt.run.configuration.name"), project, configurationFactory);
  }

  public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
    return new GwtRunConfigurationEditor(getProject());
  }

  public RunProfileState getState(DataContext context,
                                  RunnerInfo runnerInfo,
                                  RunnerSettings runnerSettings,
                                  ConfigurationPerRunnerSettings configurationSettings) throws ExecutionException {
    if (!GwtConfiguration.getInstance().isValidConfiguration()) {
      throw new ExecutionException(GwtBundle.message("error.text.gwt.not.configured"));
    }

    if (getModule() == null) {
      throw new ExecutionException(GwtBundle.message("error.text.no.gwt.module.specified"));
    }
    final Module module = getModule();
    final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
    final ProjectJdk jdk = rootManager.getJdk();
    if (jdk == null) {
      throw CantRunException.noJdkForModule(getModule());
    }

    final JavaCommandLineState state = new GwtCommandLineState(
            module, runnerSettings, configurationSettings, RUN_PAGE,
            VM_PARAMETERS, NO_SERVER, SERVER_URL);

    state.setConsoleBuilder(TextConsoleBuilderFactory.getInstance().createBuilder(getProject()));
    state.setModulesToCompile(getModules());
    return state;
  }

  public void checkConfiguration() throws RuntimeConfigurationException {
    getConfigurationModule().checkForWarning();
  }


  public Collection<Module> getValidModules() {
    return getAllModules();
  }

  protected ModuleBasedConfiguration createInstance() {
    return new GwtRunConfiguration(getName(), getProject(), GwtRunConfigurationType.getFactory());
  }

  public @Nullable Module getModule() {
    return getConfigurationModule().getModule();
  }

  public void readExternal(Element element) throws InvalidDataException {
    DefaultJDOMExternalizer.readExternal(this, element);
    readModule(element);
    super.readExternal(element);
  }

  public void writeExternal(Element element) throws WriteExternalException {
    writeModule(element);
    DefaultJDOMExternalizer.writeExternal(this, element);
    super.writeExternal(element);
  }
}
